﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace DefeatEpidemic.Common
{
    public class WinxinHelper
    {
        /// <summary>
        /// 获取小程序token
        /// </summary>
        /// <returns></returns>
        public static string GetWxAccessToken()
        {
            string accessToken = "";
            RedisExchange redis = new RedisExchange();
            if (redis.StringGet("access_token") != null)
            {
                accessToken = redis.StringGet("access_token").ToString();
            }
            if (string.IsNullOrEmpty(accessToken))
            {
                string appId = ConfigurationHelper.GetSectionValue("AppId");
                string appSerect = ConfigurationHelper.GetSectionValue("AppSecret");
                string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, appSerect);
                string ret = SendRequest(url, Encoding.UTF8, "").ReadToEnd();
                Newtonsoft.Json.Linq.JObject json = Newtonsoft.Json.Linq.JObject.Parse(ret);
                accessToken = json["access_token"].ToString();
                int expires_in = Convert.ToInt32(json["expires_in"]) / 2;//保守取值，取其剩余时间的一半，设定为过期时间
                //redis.StringSet("access_token", accessToken, DateTime.Now.AddHours(1) - DateTime.Now);
                redis.StringSet("access_token", accessToken, DateTime.Now.AddSeconds(expires_in) - DateTime.Now);
            }
            return accessToken;
        }
        /// <summary>
        /// 获取微信用户基本信息
        /// </summary>
        /// <param name="app_id"></param>
        /// <param name="app_key"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static Dictionary<string, object> GetWxUserBaseInfo(string app_id, string app_secret, string code)
        {
            //string send_url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + app_id + "&secret=" + app_key + "&js_code=" + code + "&grant_type=authorization_code";
            string send_url = string.Format("https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code", app_id, app_secret, code);
            //发送并接受返回值，不关注公众账号是无法获取oauth_unionid
            string result = HttpGet(send_url);
            if (result.Contains("errcode"))
            {
                return null;
            }
            try
            {
                Dictionary<string, object> dic = JsonHelper.JsonDeserialize<Dictionary<string, object>>(result);
                return dic;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 获取小程序二维码
        /// </summary>
        /// <param name="accessToken">接口调用凭证</param>
        /// <param name="scene">最大32个可见字符，只支持数字，大小写英文以及部分特殊字符：!#$&'()*+,/:;=?@-._~，其它字符请自行编码为合法字符（因不支持%，中文无法使用 urlencode 处理，请使用其他编码方式）</param>
        /// <param name="page">必须是已经发布的小程序存在的页面（否则报错），例如 pages/index/index ,根路径前不要填加 /,不能携带参数（参数请放在scene字段里），如果不填写这个字段，默认跳主页面</param>
        /// <param name="width">二维码的宽度，默认为 430px</param>
        /// <returns></returns>
        public static string GetWxShareCode(string scene, string page = "", int width = 430, string img_name = "", bool is_hyaline = false)
        {
            string path = "";
            string accessToken = GetWxAccessToken();
            if (page == "{page}")
                page = "";
            string url = string.Format("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={0}", accessToken);
            StringBuilder sb = new StringBuilder();
            sb.Append("{");
            sb.Append("\"scene\": \"" + scene + "\"");
            if (!string.IsNullOrEmpty(page))
            {
                sb.Append(",\"page\": \"" + page + "\"");
            }
            if (is_hyaline)
            {
                sb.Append(",\"is_hyaline\": true");
            }
            sb.Append(",\"width\": " + width + " ");
            sb.Append("}");
            string content = sb.ToString();
            path = PostMothsImg(url, content, img_name);
            if (string.IsNullOrEmpty(path))
            {
                return "";
            }
            return path;
        }

        
        /// <summary>
        /// 推送
        /// </summary>
        /// <param name="openid"></param>
        /// <param name="keyword1"></param>
        /// <param name="keyword2"></param>
        /// <param name="keyword3"></param>
        /// <param name="keyword4"></param>
        /// <param name="msg_tmpid"></param>
        /// <returns></returns>
        public static async Task<int> PushMessageAsync(string openid, string keyword1 = "", string keyword2 = "", string keyword3 = "", string keyword4 = "", string msg_tmpid = "")
        {
            string accessToken = GetWxAccessToken();
            string url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
            
            if (string.IsNullOrEmpty(msg_tmpid))
                msg_tmpid = ConfigurationHelper.GetSectionValue("MsgID");
            StringBuilder sbparams = new StringBuilder();
            sbparams.Append("{");
            sbparams.Append("\"touser\": \"" + openid + "\"");
            sbparams.Append(",\"template_id\": \"" + msg_tmpid + "\"");
            sbparams.Append(",\"page\": \"/pages/index/index\"");
            sbparams.Append(",\"data\": {");
            if (!string.IsNullOrEmpty(keyword1)) sbparams.Append("\"thing2\": {\"value\": \"" + keyword1 + "\"},");
            if (!string.IsNullOrEmpty(keyword2)) sbparams.Append("\"phrase3\": {\"value\": \"" + keyword2 + "\"},");
            if (!string.IsNullOrEmpty(keyword3)) sbparams.Append("\"date8\": {\"value\": \"" + keyword3 + "\"},");
            if (!string.IsNullOrEmpty(keyword4)) sbparams.Append("\"thing5\": {\"value\": \"" + keyword4 + "\"}");            
            sbparams.Append("}");
            sbparams.Append("}");
            //LogHelper.WriteLog(sbparams.ToString());
            NLogUtil.fileLogger.Trace(sbparams.ToString());
            PostMoths(url, sbparams.ToString());
            await Task.Delay(100);
            return 0;
        }

        /// <summary>
        /// 获取微信人脸核身信息
        /// </summary>
        /// <param name="verify_result"></param>
        /// <returns></returns>
        public static string GetIdentityInfo(string verify_result)
        {
            string accessToken = GetWxAccessToken();
            string url = "https://api.weixin.qq.com/cityservice/face/identify/getinfo?access_token=" + accessToken;
            StringBuilder sbparams = new StringBuilder();
            sbparams.Append("{");
            sbparams.Append("\"verify_result\": \"" + verify_result + "\"");
            sbparams.Append("}");
            //LogHelper.WriteLog(sbparams.ToString());
            string jsonStr = httpPost(url, sbparams.ToString());
            return jsonStr;
        }
        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="marki_id"></param>
        /// <returns></returns>
        //public static string CreateQrCode(string guid, string content)
        //{
        //    string path = "";
        //    ZXing.Common.EncodingOptions options = null;
        //    BarcodeWriter writer = null;
        //    options = new ZXing.QrCode.QrCodeEncodingOptions
        //    {
        //        DisableECI = true,
        //        CharacterSet = "UTF-8",
        //        Width = 300,
        //        Height = 300
        //    };
        //    writer = new BarcodeWriter();
        //    writer.Format = BarcodeFormat.QR_CODE;
        //    writer.Options = options;


        //    string fileName = guid.ToString() + ".jpg";
        //    using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
        //    {
        //        Bitmap bitmap = writer.Write(content);
        //        bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
        //        byte[] data = new byte[stream.Length];
        //        stream.Seek(0, System.IO.SeekOrigin.Begin);
        //        stream.Read(data, 0, Convert.ToInt32(stream.Length));
        //        Common.FIleUpload upLoad = new FIleUpload();
        //        path = upLoad.FileSaveAs(data, fileName, 0, 2);
        //    }
        //    return path;
        //}


        /// <summary>
        /// SHA1加密
        /// </summary>
        /// <param name="content"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public static string SHA1(string content, Encoding encode)
        {
            try
            {
                SHA1 sha1 = new SHA1CryptoServiceProvider();
                byte[] bytes_in = encode.GetBytes(content);
                byte[] bytes_out = sha1.ComputeHash(bytes_in);
                sha1.Dispose();
                string result = BitConverter.ToString(bytes_out);
                result = result.Replace("-", "");
                return result.ToLower();
            }
            catch (Exception ex)
            {
                throw new Exception("SHA1加密出错：" + ex.Message);
            }
        }
        /// <summary>
        /// 定向推送自定义消息
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        //public static ResponseMpMessage PushSelfMessage(RequestMpMsgModel model)
        //{
        //    string url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + model.access_token;
        //    //string mp_params = JsonHelper.ObjectToJSON(model);

        //    StringBuilder sbparams = new StringBuilder();
        //    sbparams.Append("{");
        //    sbparams.Append("\"touser\": \"" + model.touser + "\"");
        //    sbparams.Append(",\"msgtype\": \"" + model.msgtype + "\"");// 0kS_Z5n5mHpcJLzUNcGH_yj2oIoL_6wXdaq5qc6yQX4--中科主体的模板 aDaLDgXqBWYogGeB3ldPtMTYRKtSMzBnI0Pv0zfVw--科学营主体的模板
        //    sbparams.Append(",\"text\": {");
        //    sbparams.Append("\"content\": \"" + model.content + "\"");
        //    sbparams.Append("}");
        //    sbparams.Append("}");
        //    string ret = httpPost(url, sbparams.ToString());
        //    ResponseMpMessage resp = JsonHelper.JSONToObject<ResponseMpMessage>(ret);
        //    return resp;
        //}

        //-----------------------------调用的基本方法（以下包含多种请求方法，大致类似，此处未做区别，后续应该统一）---------------------------------//

        /// <summary>
        /// 流读取器
        /// </summary>        
        /// <returns></returns>
        private static StreamReader SendRequest(string url, Encoding encoding, string content, string method = "GET", string ContentType = "application/json")
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.Method = method;
            if (!string.IsNullOrEmpty(content))
            {
                using (StreamWriter dataStream = new StreamWriter(webRequest.GetRequestStream()))
                {
                    dataStream.Write(content);
                    dataStream.Close();
                }
            }
            HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
            StreamReader sr = new StreamReader(webResponse.GetResponseStream(), encoding);
            return sr;
        }

        ///将数据流转为byte[]
        public static byte[] StreamToBytes(Stream stream)
        {
            List<byte> bytes = new List<byte>();
            int temp = stream.ReadByte();
            while (temp != -1)
            {
                bytes.Add((byte)temp);
                temp = stream.ReadByte();
            }
            return bytes.ToArray();
        }

        //请求处理
        private static void PostMoths(string url, string param)
        {
            string strURL = url;
            System.Net.HttpWebRequest request;
            request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strURL);
            request.Method = "POST";
            request.ContentType = "application/json;charset=UTF-8";
            string paraUrlCoded = param;
            byte[] payload;
            payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
            request.ContentLength = payload.Length;
            System.IO.Stream writer = request.GetRequestStream();
            writer.Write(payload, 0, payload.Length);
            writer.Close();
            System.Net.HttpWebResponse response;
            response = (System.Net.HttpWebResponse)request.GetResponse();            
            System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8"));
            NLogUtil.fileLogger.Trace(reader.ReadToEnd());
        }


        //请求处理，返回二维码图片
        private static string PostMothsImg(string url, string param, string img_name)
        {
            string strURL = url;
            System.Net.HttpWebRequest request;
            request = (System.Net.HttpWebRequest)WebRequest.Create(strURL);
            request.Method = "POST";
            request.ContentType = "application/json;charset=UTF-8";
            string paraUrlCoded = param;
            byte[] payload;
            payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);
            request.ContentLength = payload.Length;
            Stream writer = request.GetRequestStream();
            writer.Write(payload, 0, payload.Length);
            writer.Close();
            System.Net.HttpWebResponse response;
            response = (System.Net.HttpWebResponse)request.GetResponse();
            System.IO.Stream s;
            s = response.GetResponseStream();//返回图片数据流
            byte[] tt = StreamToBytes(s);//将数据流转为byte[]
            if (tt.Length < 10000)
            {
                return "";
            }
            if (string.IsNullOrEmpty(img_name))
                img_name = DateTime.Now.ToString("yyyyMMddhhmmss") + ".jpg";
            ////string path = BceFileHelper.UploadFileToBosSingle(img_name, tt);
            //string path = System.Environment.CurrentDirectory + "\\XCX_CODE";
            //if (!Directory.Exists(path))
            //    Directory.CreateDirectory(path);
            //Image img = byteArrayToImage(tt);
            //string filename = Path.Combine(path, img_name);
            //img.Save(filename);
            //return filename;
            string ret_url = FIleUpload.FileSaveAs(tt, img_name);
            return ret_url;
        }

        private static string httpPost(string host, string jsonstr, int requestType = 0)
        {
            try
            {
                Encoding encoding = Encoding.Default;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
                request.Method = "post";
                request.KeepAlive = true;
                if (requestType == 1)
                {
                    request.ContentType = "application/x-www-form-urlencoded";
                    encoding = Encoding.UTF8;
                }
                else if (requestType == 2)
                {
                    request.ContentType = "application/json;charset=utf-8";
                    encoding = Encoding.UTF8;
                }
                byte[] buffer = encoding.GetBytes(jsonstr);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), encoding);
                string result = reader.ReadToEnd();
                return result;
            }
            catch (Exception ex)
            {
                return "error:" + ex.Message;
            }
        }

        /// <summary>
        /// 字节数组生成图片
        /// </summary>
        /// <param name="Bytes">字节数组</param>
        /// <returns>图片</returns>
        private static Image byteArrayToImage(byte[] Bytes)
        {
            using (MemoryStream ms = new MemoryStream(Bytes))
            {
                Image outputImg = Image.FromStream(ms);
                return outputImg;
            }
        }

        /// <summary>
        /// HTTP GET方式请求数据.
        /// </summary>
        /// <param name="url">URL.</param>
        /// <returns></returns>
        private static string HttpGet(string url)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
            request.Method = "GET";
            //request.ContentType = "application/x-www-form-urlencoded";
            request.Accept = "*/*";
            request.Timeout = 15000;
            request.AllowAutoRedirect = false;
            WebResponse response = null;
            string responseStr = null;

            try
            {
                response = request.GetResponse();
                if (response != null)
                {
                    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    responseStr = reader.ReadToEnd();
                    reader.Close();
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                request = null;
                response = null;
            }
            return responseStr;
        }
    }
}
